home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Languages / PowerMacOberon 1.2 / Source / Tools / Timer.Mod (.txt) < prev    next >
Oberon Text  |  1995-08-22  |  4KB  |  119 lines

  1. Syntax10.Scn.Fnt
  2. FoldElems
  3. Syntax10.Scn.Fnt
  4. Syntax10b.Scn.Fnt
  5. FoldElems
  6. Syntax10.Scn.Fnt
  7. MODULE Demo;
  8.         IMPORT Timer;
  9.         PROCEDURE P;
  10.         BEGIN
  11.             Timer.Start(1);
  12.             ...
  13.             Timer.Stop
  14.         END P;
  15.         PROCEDURE Q;
  16.         BEGIN
  17.             Timer.Start(2);
  18.             ...
  19.             Timer.Stop
  20.         END Q;
  21.     BEGIN
  22.         Timer.Init;
  23.         Timer.Print;
  24.     END Demo.
  25. Syntax10i.Scn.Fnt
  26. (* This module was designed for measuring the execution times of procedures but it can
  27. also be used to measure the execution time of any code.
  28.     The module maintains a list of timers that can be initialized with Timer.Init and
  29. print with Timer.Print. Timer n can be started with Timer.Start(n) and stopped with
  30. Timer.Stop. The output shows the execution times of all timers (excluding nested timers)
  31. as well as the number of calls (start/stop pairs) for every timer and the relative time
  32. per call.
  33. Sample module
  34. Syntax10i.Scn.Fnt
  35. StampElems
  36. Alloc
  37. 4 May 95
  38. Syntax10b.Scn.Fnt
  39. Documentation
  40. MODULE Timer;    (*HM 
  41. IMPORT Oberon, Out;
  42. CONST
  43.     maxCtr = 70;
  44.     maxStackSize = 256;
  45.     lastTime: LONGINT;  (*for TimeDiff*)
  46.     overhead: LONGINT;  (*overhead for measurements*)
  47.     stack:  ARRAY maxStackSize OF INTEGER;  (*timer stack*)
  48.     sp: INTEGER;  (*stack pointer*)
  49.     maxLevel: INTEGER;  (*max. timer nesting level*)
  50.     cur:  INTEGER;  (*current counter*)
  51.     counter: ARRAY maxCtr OF RECORD
  52.         time, count: LONGINT
  53.     END;
  54. PROCEDURE TimeDiff* (): LONGINT;
  55.     VAR t: LONGINT; diff: LONGINT;
  56. BEGIN
  57.     t := Oberon.Time(); diff := t - lastTime; lastTime := t;
  58.     RETURN diff
  59. END TimeDiff;
  60. PROCEDURE Init*;
  61.     VAR i: INTEGER;
  62. BEGIN
  63.     FOR i := 0 TO maxCtr-1 DO counter[i].count := 0; counter[i].time := 0 END;
  64.     sp := -1; cur := 0; maxLevel := 0; overhead := 0; lastTime := Oberon.Time()
  65. END Init;
  66. PROCEDURE Start* (n: INTEGER);
  67.     VAR t: LONGINT;
  68. BEGIN
  69.     t := TimeDiff();
  70.     INC(counter[cur].time, t);
  71.     INC(sp);
  72.     stack[sp] := cur; cur := n;
  73.     IF sp > maxLevel THEN maxLevel := sp END;
  74.     INC(overhead, TimeDiff())
  75. END Start;
  76. PROCEDURE Stop*;
  77.     VAR t: LONGINT;
  78. BEGIN
  79.     t := TimeDiff();
  80.     INC(counter[cur].time, t); INC(counter[cur].count);
  81.     cur := stack[sp]; DEC(sp);
  82.     INC(overhead, TimeDiff())
  83. END Stop;
  84. PROCEDURE Print*;
  85.     VAR totalTime, totalCount, tcall, percent: LONGINT; i, n, error: INTEGER;
  86. BEGIN
  87.     IF sp >= 0 THEN Out.String("$Timer.Print called at level > 0$"); HALT(99) END;
  88.     INC(counter[0].time, TimeDiff()); INC(counter[0].count);
  89.     n := maxCtr - 1;
  90.     WHILE counter[n].count = 0 DO DEC(n) END;
  91.     totalTime := 0; totalCount := 0;
  92.     FOR i := 0 TO n DO
  93.         counter[i].time := counter[i].time * 10 DIV 3; (* * 1000 DIV 300 *)    
  94.         (*error := (counter[i].calls + counter[i].count) DIV 88
  95.         IF error > counter[i].time THEN error := counter[i].time END;
  96.         DEC(counter[i].time, error); INC(overhead, error);*)
  97.         INC(totalTime, counter[i].time); INC(totalCount, counter[i].count)
  98.     END;
  99.     Out.String("  Ctr |  freq.  | time [ms] | time [%] | time/call |$");
  100.     Out.String("------+---------+-----------+----------+-----------+$");
  101.     FOR i := 0 TO n DO
  102.         IF totalTime = 0 THEN percent := 0 ELSE percent := counter[i].time * 1000 DIV totalTime END;
  103.         IF counter[i].count = 0 THEN tcall := 0 ELSE tcall := counter[i].time * 10 DIV counter[i].count END;
  104.         Out.Int(i, 4); Out.String("  |"); Out.Int(counter[i].count, 8); Out.String(" |"); Out.Int(counter[i].time, 8); Out.String("   |");
  105.         Out.Int(percent DIV 10, 5); Out.Char("."); Out.Int(percent MOD 10, 1); Out.String("   |");
  106.         Out.Int(tcall DIV 10, 6); Out.Char("."); Out.Int(tcall MOD 10, 1); Out.String("   |$")
  107.         END;
  108.     Out.String("------+---------+-----------+----------+-----------+$");
  109.     Out.String("total |"); Out.Int(totalCount, 8); Out.String(" |"); Out.Int(totalTime, 8);
  110.     Out.String("   |  100.0   |           |$$");
  111.     Out.String("Maximum nesting level = "); Out.Int(maxLevel, 0);
  112.     Out.String("$Timing and counting overhead = ");
  113.     overhead := overhead * 10 DIV 3; (* * 1000 DIV 300 *)
  114.     Out.Int(overhead, 0); Out.String(" ms$")
  115. END Print;
  116. BEGIN
  117.     Init
  118. END Timer.
  119.